//
// Created by jmm on 17-6-5.
//
#include "com_example_jmm_myndk_MyNdk.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdlib.h>

#include <memory.h>
#include <assert.h>
#include "avi_writer.h"

#include "c270.h"

#include <android/log.h>
#include "_onload.h"
#include "utilbase.h"

#ifndef V4L2_PIX_FMT_H264
#define V4L2_PIX_FMT_H264  0x34363248 /*  H264 stream     */
#endif

#ifndef V4L2_PIX_FMT_MJPG
#define V4L2_PIX_FMT_MJPG  0x47504A4D /*  mjpeg stream     */
#endif


jint JNI_OnLoad(JavaVM *vm, void *reserved) {
#if LOCAL_DEBUG
    LOGD("JNI_OnLoad");
#endif

    JNIEnv *env;
    if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return JNI_ERR;
    }
    setVM(vm);
#if LOCAL_DEBUG
    LOGD("JNI_OnLoad:finshed:result=%d", result);
#endif
    return JNI_VERSION_1_6;
}

static void video_capture_frame(void *buffer, int buf_len, int64_t ts, void* user_data)
{
/////////////////////////////////////avi_write///////////////////////////////
/*
	AW_CTX *aw_ctx = (AW_CTX*)user_data;

	if (AW_AddFrame(aw_ctx, 0,(unsigned char*) buffer, buf_len,1) != AW_OK) {
		//printf("Error writing frame. Stopping recording.\n");
		return;
	}
 */
    unsigned char *data = (unsigned char*)buffer;
    LOGI("-------%x-%x-%x-%x-%x-%x---------framesize=%d\n",
           *data,*(data+1),*(data+2),*(data+3), *(data+4), *(data+5), buf_len);
}

static void error_message(char* error_message)
{
    printf("error message: %s\n", error_message);
}


JNIEXPORT jstring JNICALL Java_com_example_jmm_myndk_MyNdk_nativelist
  (JNIEnv *env, jobject obj){
        SOERR ret = SOERR_NONE;
        ret = c270_init();
        if(ret != SOERR_NONE)
        {
              LOGI("456");
              c270_uninit();
              return (*env).NewStringUTF("false::ret != SOERR_NONE");
        }
        return (*env).NewStringUTF("false::ret == SOERR_NONE");
  }

  /*
          SOERR ret = SOERR_NONE;
          int loop = 10;
          VideoResList *res_list;
          VideoRes *video_res = NULL;
          int i =0;
          ret = c270_init();
          LOGI("123");
          if(ret != SOERR_NONE)
          {
              LOGI("456");
              c270_uninit();
          	return (*env).NewStringUTF("false::ret != SOERR_NONE");
          }

          c270_list_res(&res_list);

          for(i=0; i<res_list->num_res; i++)
          {
          	if(res_list->video_res[i].width == 1280 &&
          	res_list->video_res[i].height==720 &&
          	(res_list->video_res[i].format==0x47504A4D))
          	{
          		video_res = &res_list->video_res[i];
          		break;
          	}
          }
          if(video_res==NULL)
          {
              c270_uninit();
          	return (*env).NewStringUTF("false::video_res==NULL");
          }
          unsigned char *frame_buffer = (unsigned char*)malloc(512*1024);
          //const char *str = env->GetStringUTFChars(filename);
          FILE *fp = fopen("/sdcard/sunny/recsunny.avi", "wb");
          AW_CTX *aw_ctx = NULL;
          if (AW_FInit(&aw_ctx, fp, 1270, 720) != AW_OK)
          {
              return (*env).NewStringUTF("false::AW_FInit failed");
          }
          if (AW_AddVideoStream(aw_ctx, "MJPG", 16) != AW_OK || AW_StartStreamsData(aw_ctx) != AW_OK)
          {
              AW_FDone(aw_ctx);
              return (*env).NewStringUTF("false::AW_StartStreamsData failed");
          }

          ret = c270_run(video_res,  video_capture_frame, error_message, aw_ctx);

          if(ret != SOERR_NONE)
          {
              c270_uninit();
              return (*env).NewStringUTF("false::c270_run failed");
          }
          while(loop-->0)
          {
              sleep(1);
          }
          c270_stop();
          /////////////////////////avi_write///////////////////////////
          AW_UpdateStreamHeaderField(aw_ctx, 0, AW_SHDR_Scale, 100);
          AW_UpdateStreamHeaderField(aw_ctx, 0, AW_SHDR_Rate, 30*100);

          AW_FDone(aw_ctx);

          return (*env).NewStringUTF("true::avi file was closed!");

  */

  JNIEXPORT jstring JNICALL Java_com_example_jmm_myndk_MyNdk_nativestart
    (JNIEnv *env, jobject obj, jstring filename){
      SOERR ret = SOERR_NONE;
      int loop = 10;
      VideoResList *res_list;
      VideoRes *video_res = NULL;
      int i =0;
      ret = c270_init();
      LOGI("123");
      if(ret != SOERR_NONE)
      {
          LOGI("456");
          c270_uninit();
          return (*env).NewStringUTF("false::ret != SOERR_NONE");
      }

      c270_list_res(&res_list);

      for(i=0; i<res_list->num_res; i++)
      {
          if(res_list->video_res[i].width == 1000 &&
             res_list->video_res[i].height==1000 &&
             (res_list->video_res[i].format==V4L2_PIX_FMT_MJPG))
          {
              video_res = &res_list->video_res[i];
              break;
          }
      }
      if(video_res==NULL)
      {
          c270_uninit();
          return (*env).NewStringUTF("false::video_res==NULL");
      }
      unsigned char *frame_buffer = (unsigned char*)malloc(512*1024);
      //const char *str = env->GetStringUTFChars(filename);
/*
      FILE *fp = fopen("/sdcard/sunny/recsunny.avi", "wb");
      AW_CTX *aw_ctx = NULL;
      if (AW_FInit(&aw_ctx, fp, 1270, 720) != AW_OK)
      {
          return (*env).NewStringUTF("false::AW_FInit failed");
      }
      if (AW_AddVideoStream(aw_ctx, "MJPG", 16) != AW_OK || AW_StartStreamsData(aw_ctx) != AW_OK)
      {
          AW_FDone(aw_ctx);
          return (*env).NewStringUTF("false::AW_StartStreamsData failed");
      }
*/
      ret = c270_run(video_res,  video_capture_frame, error_message, NULL);

      if(ret != SOERR_NONE)
      {
          c270_uninit();
          return (*env).NewStringUTF("false::c270_run failed");
      }
      while(loop-->0)
      {
          sleep(1);
      }
      c270_stop();
      /////////////////////////avi_write///////////////////////////
/*
      AW_UpdateStreamHeaderField(aw_ctx, 0, AW_SHDR_Scale, 100);
      AW_UpdateStreamHeaderField(aw_ctx, 0, AW_SHDR_Rate, 30*100);

      AW_FDone(aw_ctx);
*/
      return (*env).NewStringUTF("true::avi file was closed!");
    }

JNIEXPORT jstring JNICALL Java_com_example_jmm_myndk_MyNdk_nativestop
  (JNIEnv *env, jobject obj){
        return (*env).NewStringUTF("----------------------");
  }